/**
 * 功能描述：创建本地网络服务器，建立AP热点，手机连接wifi热点ESPiot_AP，登录浏览器可以控制灯的亮灭，可以请求访问www.Espiot.com/LedOn打开灯，www.Espiot.com/LedOff关灯
 */

#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <TaskScheduler.h>
#include <ArduinoJson.h> 
//调试定义
#define DebugBegin(baud_rate)    Serial.begin(baud_rate)
#define DebugPrintln(message)    Serial.println(message)
#define DebugPrint(message)    Serial.print(message)
#define DebugPrintF(...) Serial.printf( __VA_ARGS__ )
#define LED_BUILTIN 2
const byte DNS_PORT = 53;
IPAddress apIP(192, 168, 1, 1);
DNSServer dnsServer;
ESP8266WebServer webServer(80);
String jsonData;
String tempjsonString;  

int temperature;
Scheduler runner;

void t1Callback();
Task t1(3000, TASK_FOREVER, &t1Callback);
void t1Callback() {
    //  b++;
    // Serial.print("t2 的次数:  ");
    // Serial.println(b);
    task1();
}

void setup() {

  DebugBegin(115200);
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP("ESPiot_AP");
  pinMode(LED_BUILTIN, OUTPUT); //设置内置LED引脚为输出模式以便控制LED
  // modify TTL associated  with the domain name (in seconds)
  // default is 60 seconds
  dnsServer.setTTL(300);
  // set which return code will be used for all other domains (e.g. sending
  // ServerFailure instead of NonExistentDomain will reduce number of queries
  // sent by clients)
  // default is DNSReplyCode::NonExistentDomain
  dnsServer.setErrorReplyCode(DNSReplyCode::ServerFailure);

  // 启动DNS server，映射主机名为 www.Espiot.com
  bool status = dnsServer.start(DNS_PORT, "www.Espiot.com", apIP);

  if(status){
      DebugPrintln("start dnsserver success.");
  }else{
     DebugPrintln("start dnsserver failed.");
  }

  // simple HTTP server to see that DNS server is working
  // webServer.onNotFound([]() {
  //   String message = "Hello World!\n\n";
  //   message += "URI: ";
  //   message += webServer.uri();

  //   webServer.send(200, "text/plain", message);
  // });
   webServer.begin();                           // 启动网站服务
   webServer.on("/", HTTP_GET, handleRoot);     // 设置服务器根目录即'/'的函数'handleRoot'
   webServer.on("/LedOn", HTTP_POST, handleLedOn);  // 设置处理LED控制请求的函数'handleLedOn'
   webServer.on("/LedOff", HTTP_POST, handleLedOff);  // 设置处理LED控制请求的函数'handleLedOff'
   webServer.on("/temp", HTTP_POST, handletemp);  // 设置处理LED控制请求的函数'handletemp'
   webServer.onNotFound(handleNotFound);        // 设置处理404情况的函数'handleNotFound'
   Serial.println("HTTP esp8266_server started");//  告知用户ESP8266网络服务功能已经启动
   runner.init();
  Serial.println("Initialized scheduler");  
  runner.addTask(t1);
  Serial.println("added t1");
  t1.enable();
  Serial.println("Enabled t1");
}

void loop() {
  dnsServer.processNextRequest();
  webServer.handleClient();
  runner.execute();
}

void handleRoot() {      
  String str;
   webServer.send(200, "text/plain", "Hello from ESP8266!");  
//  str =  "<form action=\"/LedOn\" method=\"POST\"><input type=\"submit\" value=\"Turn on LED\"></form>";
//  str += "<form action=\"/LedOff\" method=\"POST\"><input type=\"submit\" value=\"Turn off LED\"></form>";
//  str += "<form action=\"/StreamLed\" method=\"POST\"><input type=\"submit\" value=\"Stream Led\"></form>";
//  webServer.send(200, "text/html", str);
}
 
//处理LED控制请求的函数'handleLED'
void handleLedOn() {
  Serial.println("  开灯");    
                 
  digitalWrite(LED_BUILTIN,1);// 改变LED的点亮或者熄灭状态
  webServer.send(200,"text/plain", "灯已开");
  delay(50);
  webServer.on("/", HTTP_GET, handleRoot);     // 设置服务器根目录即'/'的函数'handleRoot'
}

void handleLedOff() { 
  Serial.println("  关灯");     
                   
  digitalWrite(LED_BUILTIN,0);// 改变LED的点亮或者熄灭状态
  webServer.send(200,"text/plain", "灯已关");
  delay(50);
  webServer.on("/", HTTP_GET, handleRoot);     // 设置服务器根目录即'/'的函数'handleRoot'
}

// 设置处理404情况的函数'handleNotFound'
void handleNotFound(){
  webServer.send(404, "text/plain", "404: Not found"); // 发送 HTTP 状态 404 (未找到页面) 并向浏览器发送文字 "404: Not found"
}

void handletemp(){
   webServer.send(200, "text/plain", tempjsonString);
   Serial.print(" 已发送温度： ");  Serial.println(tempjsonString);     
}

void task1(){
    // 创建JSON数据格式  
  int min= 20;  
  int max= 39;  
   temperature = random(max - min + 1) + min;  
  // jsonData = "{\"temperature\":";  
  // jsonData += temperature;  
  // jsonData += "}";  
  // 输出JSON数据到串口监视器  
  // Serial.println(jsonData); 
  // 创建一个JSON对象  
  DynamicJsonDocument doc(1024);  
  doc["temperature"] = temperature;  
  
  // 将JSON对象转换为字符串   
  serializeJson(doc, tempjsonString);  
  
  // 通过串口发送JSON字符串  
  Serial.print("当前的温度为：");
  Serial.println(tempjsonString);  

}


